package utp.tepc.jogogeneral;

import java.util.*;
import java.io.*;

public class ViewJogo
{
    public static final int LEN_CHAR_SEPARATOR = 80;

    private Jogo jogo;
    private InputStreamReader reader;
    private BufferedReader buffer;

    public ViewJogo()
    {
	this.reader = new InputStreamReader(System.in);
	this.buffer = new BufferedReader(this.reader);
    }

    public void setJogo(Jogo j)
    {
	jogo = j;
    }

    public void viewAddJogadores() throws Exception
    {
	ViewJogo.drawCharLine('+', LEN_CHAR_SEPARATOR, true);
	System.out.println("Informe o nome dos jogadores.");
	System.out.println("Digige (S)air quando terminar de inserir os nome");
	ViewJogo.drawCharLine('+', LEN_CHAR_SEPARATOR, true);

	String op = "";

	while (!op.contains("S"))
	{
	    op = buffer.readLine();
	    jogo.adcionarJogadorDado(new JogadorDado(op));
	}

	jogo.getJogadores().remove(jogo.getJogadores().size() - 1);

	this.header();

	ViewJogo.drawCharLine('+', LEN_CHAR_SEPARATOR, true);
	System.out.println("Os seguinte jogadores foram adicionados: ");
	for (JogadorDado j : jogo.getJogadores())
	{
	    System.out.println(j.toString() + "\n");
	}
	ViewJogo.drawCharLine('+', LEN_CHAR_SEPARATOR, true);
    }

    public void header() throws IOException
    {
	Runtime.getRuntime().exec("clear");

	ViewJogo.drawCharLine('*', ViewJogo.LEN_CHAR_SEPARATOR, true);
	System.out.println("JOGO: GENERAL");
	ViewJogo.drawCharLine('*', ViewJogo.LEN_CHAR_SEPARATOR, true);
    }

    public void telaIniciarJogo()
    {
	jogo.adcionarJogadorDado(new JogadorDado("Jorge"));
	jogo.adcionarJogadorDado(new JogadorDado("Tadeu"));

	ViewJogo.drawCharLine('#', LEN_CHAR_SEPARATOR, true);
	System.out.println("INICIO DE JOGO");
	ViewJogo.drawCharLine('#', LEN_CHAR_SEPARATOR, true);

	jogo.iniciarJogo();
	System.out.println("Rodada: " + jogo.getRodada());
	while (jogo.fimJogo())
	{
	    ViewJogo.drawCharLine('=', LEN_CHAR_SEPARATOR, true);
	    System.out.println("Agora jogando: " + jogo.getJogadorAtual().toString());
	    ViewJogo.drawCharLine('=', LEN_CHAR_SEPARATOR, true);

	    try
	    {
		jogo.setDadosJogador();

		while (jogo.temLances())
		{
		    jogo.jogadorLanca();
		    char op = telaResultadoLancamento(jogo.jogadasPossiveis(), jogo.getQtdLance());

		    if (isValidValue("Mm".toCharArray(), op) || !jogo.temLances())
		    {
			ViewJogo.drawCharLine('/', 80, true);
			telaMarcarPonto(jogo.getJogadorAtual());
			ViewJogo.drawCharLine('/', 80, true);
		    }

		    if (isValidValue("Ss".toCharArray(), op) && jogo.temLances())
			telaSelecionarDados();
		}

		ViewJogo.drawCharLine('=', LEN_CHAR_SEPARATOR, true);
		jogo.proxJogador();

		if (jogo.todosJogaramRodada())
		{
		    jogo.proxRodada();
		    System.out.println("Rodada: " + jogo.getRodada());
		}
	    }
	    catch (Exception e)
	    {
		e.printStackTrace();
	    }

	}

	System.out.println("JOGO GENERAL FINALIZADO");

    }

    public char telaResultadoLancamento(HashMap<Integer, String> jogadas, int qtdLanc) throws Exception
    {
	String opMarcar = "mM";
	String opSelLanc = "LlSs";
	String opVer = "Vv";
	char[] opValids;

	ViewJogo.drawCharLine('-', 80, true);
	System.out.print("Resusltado do lancamento: ");
	System.out.println(jogo.getValoresLanc());
	ViewJogo.drawCharLine('-', 80, true);

	if (jogadas.size() > 0)
	{
	    System.out.println("No lancamento " + qtdLanc + " os jogos possíveis são:");
	    this.telaJogada(jogadas);
	}

	if (!jogo.temLances())
	{
	    System.out.println("Digite (M)arcar para marcar seus pontos");
	    opValids = opMarcar.toCharArray();
	}
	else
	{
	    System.out.println("Digite (M)arcar os pontos");
	    System.out.println("Digite (S)elecionar os dados que deseja deixar na mesa.");
	    System.out.println("Digite (L)ancar para fazer um novo lançamento com todos os dados.");
	    opValids = (opMarcar + opSelLanc).toCharArray();
	}

	return entradaDados(opValids);
    }

    public void telaSelecionarDados() throws Exception
    {
	String opNumValidos = "123456";
	String opValidSair = "Ss";

	ViewJogo.drawCharLine(':', 80, true);
	List<Dado> ds = jogo.getJogadorAtual().getDados();

	System.out.println("Digite o número sorteado que irá ficar na mesa.");
	System.out.println("Quando finalizar a seleção digite (S)air");

	System.out.println("Dados: " + jogo.getValoresLanc());

	char op = ' ';

	while (!isValidValue(opValidSair.toCharArray(), op))
	{
	    op = entradaDados((opNumValidos + opValidSair).toCharArray());

	    if (isValidValue(opNumValidos.toCharArray(), op))
	    {
		for (Dado d : ds)
		{
		    Integer i = Integer.parseInt(Character.toString(op));
		    if (d.getNumeroSorteado() == i)
			d.setSeleciondao(true);
		}
	    }
	}
	ViewJogo.drawCharLine(':', 80, true);
    }

    public void telaMarcarPonto(JogadorDado j) throws Exception
    {
	String opValidsNao = "Mn";
	String opValidsSim = "Ss";
	String opVisualizar = "Vv";
	String opDado = "123456";

	System.out.println("Marcar pontos: " + j);
	HashMap<Integer, String> jogadas = jogo.jogadasPossiveis();
	this.telaJogada(jogadas);

	boolean b = true;

	do
	{
	    if (jogadas.size() > 0)
	    {
		for (Integer key : jogadas.keySet())
		{
		    System.out.println("Digite (S)im para marcar essa jogada.");
		    System.out.println("Digite (V)isualizar para ver as jogdas já marcadas.");
		    System.out.println("Digite (Q)ueiamar uma jogada.");
		    char op = entradaDados((opValidsNao + opValidsSim + opVisualizar).toCharArray());

		    if (isValidValue(opValidsSim.toCharArray(), op))
			b = !jogo.marcarPorJogada(jogo.getPontuacao(key), key, j);

		    if (isValidValue(opVisualizar.toCharArray(), op))
			telaJogadasRealizadas(j);

		    if (b)
			System.out.println("Escolha outra jogada essa já foi marcada.");
		    else
			jogo.liberarDados(j);
		}
	    }
	    else
	    {
		System.out.println("Digite (V)isualizar para ver as jogdas já marcadas.");
		System.out.println("Digite (Q)ueiamar uma jogada.");

		System.out.println("Você não possui nenhum jogoda, selecione um dado para marcar.");
		dadosNaMesa();
		char op = entradaDados((opDado + opVisualizar).toCharArray());

		if (isValidValue(opVisualizar.toCharArray(), op))
		    telaJogadasRealizadas(j);

		if (isValidValue(opDado.toCharArray(), op))
		{
		    int num = Integer.parseInt(Character.toString(op));
		    int qtdNum = 0;

		    for (Dado d : j.getDados())
			if (d.getNumeroSorteado().intValue() == num)
			    qtdNum++;

		    if (jogo.isSorteado(num))
			b = !jogo.marcarPorDado(num, qtdNum, j);

		    if (b)
			System.out.println("Escolha outro dado, esse já foi marcado");
		    else
			jogo.liberarDados(j);
		}
	    }
	} while (b);
    }

    public void telaRodada()
    {
	System.out.println("Tela da rodada");

    }

    public void telaJogadasRealizadas(JogadorDado j)
    {
	ViewJogo.drawCharLine('-', 80, true);
	System.out.println("Jogadas realizado de: " + j.toString());
	ViewJogo.drawCharLine('-', 80, true);

	HashMap<Integer, Integer> pontos = j.getPontuacao();
	ViewJogo.drawCharLine('-', 80, true);
	System.out.printf("%17s | %10s", "Nome da jogadada", "Ponto");
	System.out.println();
	ViewJogo.drawCharLine('-', 80, true);
	for (Integer key : pontos.keySet())
	{
	    System.out.printf("%17s | %10s", jogo.getGeneral().getNomeJogada(key).toString(), pontos.get(key).toString());
	    System.out.println();
	    ViewJogo.drawCharLine('-', 80, true);
	}
	ViewJogo.drawCharLine('-', 80, true);
    }

    public void dadosNaMesa() throws Exception
    {
	System.out.print("Dados disponíveis para marcar: ");
	System.out.println(jogo.getValoresLanc());
	System.out.println("\nDigite a opção desejada: ");
    }

    public void telaJogada(HashMap<Integer, String> jogadas)
    {
	for (int i = 0; i < jogadas.size(); i++)

	    for (Integer key : jogadas.keySet())
		System.out.println("Jogada que pode ser marcada: " + jogadas.get(key));
    }

    public static void drawCharLine(char c, int lineLength)
    {
	for (int i = 0; i < lineLength; i++)
	    System.out.print(c);
    }

    public static void drawCharLine(char c, int lineLength, boolean breakLine)
    {
	drawCharLine(c, lineLength);
	System.out.println();
    }

    private char entradaDados(char[] valoresPossiveis) throws IOException
    {
	char value;
	boolean flag = true;

	do
	{
	    String c = buffer.readLine();

	    if (c.length() == 0)
		value = ' ';
	    else
		value = c.toCharArray()[0];

	    if (!isValidValue(valoresPossiveis, value))
	    {
		ViewJogo.drawCharLine('+', 80, true);
		System.out.println("Digitie uma opção válida.");
		ViewJogo.drawCharLine('+', 80, true);
	    }
	    else
		flag = false;

	} while (flag);

	return value;
    }

    private boolean isValidValue(char[] valoresPossiveis, char valorDigitado)
    {
	for (int i = 0; i < valoresPossiveis.length; i++)
	    if (valoresPossiveis[i] == valorDigitado)
		return true;

	return false;
    }

}
